Component({
  properties: {
    visible: { type: Boolean, value: false },
    top: { type: Number, value: 0 },
    type: { type: String, value: 'single' }, // 'single' 单选；'range' 区间
  },
  observers: {
    'top': function(top) {
      // 312为面板高度
      this.setData({ panelBottom: (parseInt(top || 0, 10) + 312) });
    }
  },
  data: {
    panelBottom: 312, // 初始为最低点
    // 组件内部生成的渲染数据
    monthLabel: '',
    weekdays: ['日','一','二','三','四','五','六'],
    calendarRows: [],
    currentYear: 0,
    currentMonth: 0, // 0-11
    // 选择状态
    selectedDate: null, // 单选
    rangeStart: null,   // 区间选开始
    rangeEnd: null      // 区间选结束
  },
  lifetimes: {
    attached() {
      const now = new Date();
      this.setData({ currentYear: now.getFullYear(), currentMonth: now.getMonth() });
      this.updateCalendar();
    }
  },
  methods: {
    onMaskTap() { this.triggerEvent('close') },
    onReset() {
      this.setData({ selectedDate: null, rangeStart: null, rangeEnd: null }, () => {
        this.updateCalendar();
      });
      this.triggerEvent('reset');
    },
    onConfirm() {
      const detail = this.data.type === 'range'
        ? { start: this.data.rangeStart, end: this.data.rangeEnd }
        : { value: this.data.selectedDate };
      this.triggerEvent('confirm', detail);
    },
    onPrevMonth() {
      let { currentYear, currentMonth } = this.data;
      currentMonth -= 1;
      if (currentMonth < 0) { currentMonth = 11; currentYear -= 1; }
      this.setData({ currentYear, currentMonth }, () => this.updateCalendar());
      this.triggerEvent('prevMonth');
    },
    onNextMonth() {
      let { currentYear, currentMonth } = this.data;
      currentMonth += 1;
      if (currentMonth > 11) { currentMonth = 0; currentYear += 1; }
      this.setData({ currentYear, currentMonth }, () => this.updateCalendar());
      this.triggerEvent('nextMonth');
    },
    onDateSelect(e) {
      const ds = e.currentTarget.dataset || {};
      const dateStr = ds.date || ds.value || ds.label;
      if (!dateStr) return;

      if (this.data.type === 'single') {
        this.setData({ selectedDate: dateStr }, () => this.updateCalendar());
        this.triggerEvent('dateSelect', { value: dateStr });
      } else {
        const { rangeStart, rangeEnd } = this.data;
        if (!rangeStart || (rangeStart && rangeEnd)) {
          this.setData({ rangeStart: dateStr, rangeEnd: null }, () => this.updateCalendar());
        } else {
          if (this.compareDate(dateStr, rangeStart) < 0) {
            this.setData({ rangeStart: dateStr, rangeEnd: rangeStart }, () => this.updateCalendar());
          } else {
            this.setData({ rangeEnd: dateStr }, () => this.updateCalendar());
          }
          this.triggerEvent('dateSelect', { start: this.data.rangeStart, end: this.data.rangeEnd });
        }
      }
    },
    updateCalendar() {
      const { currentYear, currentMonth } = this.data;
      const monthLabel = `${currentYear}年${currentMonth + 1}月`;
      const rows = this.buildCalendarRows(currentYear, currentMonth);
      const rowsWithSelection = this.applySelectionClasses(rows);
      this.setData({ monthLabel, calendarRows: rowsWithSelection });
    },
    buildCalendarRows(year, month) {
      const firstDay = new Date(year, month, 1);
      const firstWeekday = firstDay.getDay();
      const daysInMonth = new Date(year, month + 1, 0).getDate();
      const daysInPrevMonth = new Date(year, month, 0).getDate();

      const cells = [];
      for (let i = firstWeekday - 1; i >= 0; i--) {
        const day = daysInPrevMonth - i;
        const d = new Date(year, month - 1, day);
        cells.push(this.buildCell(d, false));
      }
      for (let d = 1; d <= daysInMonth; d++) {
        const date = new Date(year, month, d);
        cells.push(this.buildCell(date, true));
      }
      while (cells.length % 7 !== 0) {
        const index = cells.length - (firstWeekday + daysInMonth);
        const day = index + 1;
        const date = new Date(year, month + 1, day);
        cells.push(this.buildCell(date, false));
      }
      const rows = [];
      for (let i = 0; i < cells.length; i += 7) {
        rows.push(cells.slice(i, i + 7));
      }
      return rows;
    },
    buildCell(date, inCurrentMonth) {
      const today = new Date();
      const isToday = date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate();
      const label = String(date.getDate());
      const classList = [];
      if (!inCurrentMonth) classList.push('prev-month');
      if (isToday) classList.push('today');
      return {
        label,
        date: this.formatDate(date),
        inCurrentMonth,
        class: classList.join(' ')
      };
    },
    applySelectionClasses(rows) {
      const { type, selectedDate, rangeStart, rangeEnd } = this.data;
      const mapped = rows.map(row => row.map(cell => {
        const classes = (cell.class || '').split(' ').filter(Boolean);
        if (type === 'single' && selectedDate && cell.date === selectedDate) {
          classes.push('selected');
        }
        if (type === 'range' && rangeStart) {
          if (cell.date === rangeStart) classes.push('range-start');
          if (rangeEnd) {
            if (cell.date === rangeEnd) classes.push('range-end');
            if (this.compareDate(cell.date, rangeStart) > 0 && this.compareDate(cell.date, rangeEnd) < 0) {
              classes.push('in-range');
            }
          }
        }
        return { ...cell, class: classes.join(' ') };
      }));
      return mapped;
    },
    compareDate(a, b) {
      if (!a || !b) return 0;
      return a < b ? -1 : a > b ? 1 : 0;
    },
    formatDate(date) {
      const y = date.getFullYear();
      const m = String(date.getMonth() + 1).padStart(2, '0');
      const d = String(date.getDate()).padStart(2, '0');
      return `${y}-${m}-${d}`;
    }
  }
});
